package com.llsydn.refreshlistview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.*;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author lilinshen
 * @title 自定义下来刷新的listview
 * @description 请填写相关描述
 * @date 2018/10/29 10:32
 */
public class RefreshListView extends ListView {
    // 顶部轮播图部分
    private View topNewsView;
    // 下拉刷新和顶部轮播图
    private LinearLayout headerView;
    // 下拉刷新的控件
    private View ll_pull_down_refresh;
    // 加载更多的控件
    private View footerView;
    private ImageView iv_arrow;
    private ProgressBar pb_status;
    private TextView tv_status;
    private TextView tv_time;
    // 下拉刷新控件的高
    private int llPullDownHeight;
    private float startY = -1;
    // 下来刷新
    private static final int PULL_DOWN_REFRESH = 0;
    // 手松刷新
    private static final int RELEASE_REFRESH = 1;
    // 正在刷新
    private static final int REFRESHING = 2;
    // 当前状态
    private int currentStatus = PULL_DOWN_REFRESH;
    private Animation upAnimation;
    private Animation downAnimation;
    private int footerViewHeight;
    // 是否已经加载更多
    private boolean isLoadMore;
    // listview在y轴上的坐标
    private int listViewOnScreenY = -1;

    public RefreshListView(Context context) {
        this(context, null);
    }

    public RefreshListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initHeadView(context);
        initAnimation();
        initialFooterView(context);
    }

    private void initialFooterView(Context context) {
        footerView = View.inflate(context, R.layout.refresh_footer, null);
        footerView.measure(0, 0);
        // 默认不显示
        footerViewHeight = footerView.getMeasuredHeight();
        footerView.setPadding(0, -footerViewHeight, 0, 0);
        // listview添加footer
        addFooterView(footerView);

        setOnScrollListener(new MyOnScrollListener());

    }

    /**
     * 把顶部轮播图部分视图，以头的方式添加到listview中
     *
     * @param topNewsView
     */
    public void addTopNewsView(View topNewsView) {
        if (topNewsView != null) {
            this.topNewsView = topNewsView;
            headerView.addView(topNewsView);
        }
    }

    /**
     * 滚动监听
     */
    class MyOnScrollListener implements OnScrollListener {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            // 当静止或者惯性滚动的时候
            if (scrollState == OnScrollListener.SCROLL_STATE_IDLE || scrollState == OnScrollListener.SCROLL_STATE_FLING) {
                // 并且是最后一条可见
                if (getLastVisiblePosition() >= getCount() - 1) {
                    // 显示加载更多的布局
                    footerView.setPadding(8, 8, 8, 8);
                    // 状态改变
                    isLoadMore = true;
                    // 回调接口
                    if (null != onRefreshListener) {
                        onRefreshListener.onLoadMore();
                    }
                }
            }

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

        }
    }


    private void initAnimation() {
        upAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        upAnimation.setDuration(500);
        upAnimation.setFillAfter(true);

        downAnimation = new RotateAnimation(-180, -360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        downAnimation.setDuration(500);
        downAnimation.setFillAfter(true);
    }

    /**
     * 初始化头部
     *
     * @param context
     */
    private void initHeadView(Context context) {
        headerView = (LinearLayout) View.inflate(context, R.layout.refresh_header, null);
        // 下拉刷新控件
        ll_pull_down_refresh = headerView.findViewById(R.id.ll_pull_down_refresh);
        iv_arrow = headerView.findViewById(R.id.iv_arrow);
        pb_status = headerView.findViewById(R.id.pb_status);
        tv_status = headerView.findViewById(R.id.tv_status);
        tv_time = headerView.findViewById(R.id.tv_time);
        // 添加头
        addHeaderView(headerView);

        // 测量
        ll_pull_down_refresh.measure(0, 0);
        llPullDownHeight = ll_pull_down_refresh.getMeasuredHeight();
        // 默认隐藏下拉刷新控件
        ll_pull_down_refresh.setPadding(0, -llPullDownHeight, 0, 0);

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (startY == -1) {
                    startY = ev.getY();
                }
                // 判断顶部轮播图是否完全显示，只有完全显示，才会下拉刷新
                boolean isDisplayTopNews = isDisplayTopNews();
                if (!isDisplayTopNews) {
                    // 加载更多
                    break;
                }
                // 如果是正在刷新，就不再刷新了
                if (currentStatus == REFRESHING) {
                    break;
                }
                // 来到新的坐标
                float endY = ev.getY();
                // 计算滑动的距离
                float distanceY = endY - startY;
                if (distanceY > 0) {
                    // 下拉
                    int paddingTop = (int) (-llPullDownHeight + distanceY);

                    if (paddingTop < 0 && currentStatus != PULL_DOWN_REFRESH) {
                        // 下拉刷新状态
                        currentStatus = PULL_DOWN_REFRESH;
                        // 更新状态
                        refreshViewState();
                    } else if (paddingTop > 0 && currentStatus != RELEASE_REFRESH) {
                        // 手松刷新状态
                        currentStatus = RELEASE_REFRESH;
                        // 更新状态
                        refreshViewState();
                    }
                    ll_pull_down_refresh.setPadding(0, paddingTop, 0, 0);
                }
                break;
            case MotionEvent.ACTION_UP:
                startY = -1;
                if (currentStatus == PULL_DOWN_REFRESH) {
                    // 隐藏
                    ll_pull_down_refresh.setPadding(0, -llPullDownHeight, 0, 0);
                } else if (currentStatus == RELEASE_REFRESH) {
                    // 设置状态为正在刷新状态
                    currentStatus = REFRESHING;
                    // 显示
                    ll_pull_down_refresh.setPadding(0, 0, 0, 0);
                    // 更新状态
                    refreshViewState();

                    if (null != onRefreshListener) {
                        onRefreshListener.onPullDownRefresh();
                    }
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 判断是否完全显示顶部轮播图
     *
     * @return
     */
    private boolean isDisplayTopNews() {
        if (topNewsView != null) {
            // 得到listview在屏幕上的坐标
            int[] location = new int[2];
            if (listViewOnScreenY == -1) {
                getLocationOnScreen(location);
                listViewOnScreenY = location[1];
            }
            // 得到顶部轮播图在屏幕上的坐标
            topNewsView.getLocationOnScreen(location);
            int topNewsViewOnScreenY = location[1];
            if (listViewOnScreenY <= topNewsViewOnScreenY) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }

    /**
     * 更新状态
     */
    private void refreshViewState() {
        switch (currentStatus) {
            case PULL_DOWN_REFRESH:
                // 下拉刷新
                iv_arrow.startAnimation(downAnimation);
                tv_status.setText("下拉刷新...");
                break;
            case RELEASE_REFRESH:
                // 手松刷新
                iv_arrow.startAnimation(upAnimation);
                tv_status.setText("手松刷新...");
                break;
            case REFRESHING:
                // 正在刷新
                tv_status.setText("正在刷新...");
                pb_status.setVisibility(VISIBLE);
                iv_arrow.clearAnimation();
                iv_arrow.setVisibility(GONE);
                break;
        }
    }

    /**
     * 当联网成功和失败回调该方法
     *
     * @param result
     */
    public void onRefreshFinish(boolean result) {
        if (isLoadMore) {
            // 加载更多
            isLoadMore = false;
            // 隐藏
            footerView.setPadding(0, -footerViewHeight, 0, 0);
        } else {
            // 下拉刷新
            // 隐藏
            ll_pull_down_refresh.setPadding(0, -llPullDownHeight, 0, 0);
            tv_status.setText("下拉刷新...");
            currentStatus = PULL_DOWN_REFRESH;
            iv_arrow.clearAnimation();
            pb_status.setVisibility(GONE);
            iv_arrow.setVisibility(VISIBLE);
            if (result) {
                tv_time.setText("上次更新时间：" + getSystemTime());
            }
        }
    }

    /**
     * 获取系统的时间
     *
     * @return
     */
    private String getSystemTime() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(new Date());
    }

    /**
     * 监听下拉控件刷新接口
     */
    public interface OnRefreshListener {
        /**
         * 当下拉刷新的时候回调这个方法
         */
        public void onPullDownRefresh();

        /**
         * 当加载更多
         */
        public void onLoadMore();
    }

    private OnRefreshListener onRefreshListener;

    public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
        this.onRefreshListener = onRefreshListener;
    }
}
